﻿//Clss with analitics for wavelet transform
namespace Diplom.Wavelets
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Diplom.NumericArrays;
    
    public static class Analitics
    {
        /// <summary>
        /// Periodogramma for Fourier Transform
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Numeric1DArray Periodogramma(ref Complex1DArray source)
        {
            int m = source.Length;
            int n = (m + 1) / 2;
            Numeric1DArray res = new Numeric1DArray(n);
            for (int i = 0; i < n; i++)
            {
                double temp = (source.Items[i].Real*source.Items[i].Real+source.Items[i].Image*source.Items[i].Image)/(m*m);
                res.Insert(i, temp);
            }
            res.TimeMin -= 1;
            res.TimeMax = n/((source.TimeMax-source.TimeMin)*0.40);
            //res.TimeMax /= 2;
            res.InitCharacters();
            return res;
        }

        /// <summary>
        /// Scalogramma
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Numeric2DArray Scalogramma(ref Numeric2DArray source)
        {
            Numeric2DArray res = new Numeric2DArray(source.NSize, source.MSize);
            
            for (int i = 0; i < source.NSize; i++)
            {
                for (int j = 0; j < source.MSize; j++)
                {
                    res.Insert(i, j, source.Items[i][j] * source.Items[i][j]);
                }
            }
            res.MinFreak = source.MinFreak;
            res.MaxFreak = source.MaxFreak;
            res.MaxTime = source.MaxTime;
            res.MinTime = source.MinTime;
            res.InitCharacters();
            return res;
        }
        
        /// <summary>
        /// Sceleton
        /// </summary>
        /// <param name="source"></param>
        public static Numeric2DArray Sceleton(ref Numeric2DArray source)
        {
            Numeric2DArray res = new Numeric2DArray(source.NSize, source.MSize);
            for (int i = 0; i < source.NSize; i++)
            {
                for (int j = 0; j < source.MSize; j++)
                {
                    if (i == 0 || j == 0 || i == source.NSize - 1 || j == source.MSize - 1) res.Insert(i, j, 0.0);
                    else
                    {
                        if (source.Items[i][j] > source.Items[i - 1][j] && source.Items[i][j] > source.Items[i + 1][j]) res.Insert(i, j, source.Items[i][j]);
                        else
                        {
                            if (source.Items[i][j] > source.Items[i][j-1] && source.Items[i][j] > source.Items[i][j+1]) res.Insert(i, j, source.Items[i][j]);
                            else
                            {
                                res.Insert(i, j, 0.0);
                            }
                        }
                    }
                }
            }
            res.MinFreak = source.MinFreak;
            res.MaxFreak = source.MaxFreak;
            res.MaxTime = source.MaxTime;
            res.MinTime = source.MinTime;
            res.InitCharacters();

            return res;
        }

        /// <summary>
        /// Sceylogramma
        /// </summary>
        /// <param name="source"></param>
        /// <param name="all"></param>
        /// <returns></returns>
        public static Numeric1DArray Sceylogramma(ref Numeric2DArray source,bool all)
        {
            Numeric1DArray res = new Numeric1DArray(source.NSize);
            for (int i = 0; i < res.Length; i++)
            {
                double sum = 0;
                if (all)
                {
                    for (int j = 0; j < source.MSize; j++)
                    {
                        sum += Math.Abs(source.Items[i][j]);
                    }
                    sum /= source.MSize;
                }
                else
                {
                    #warning ХЗ пока, стоит ли писать с вырезом по краям
                }
                res.Insert(i, sum);
            }
            res.InitCharacters();
            for (int i = 0; i < res.Length; i++)
            {
                res.Items[i] += res.Average;
            }
            res.TimeMin = (int)Math.Pow(2.0, source.MinFreak);
            res.TimeMax = (int)Math.Pow(2.0, source.MaxFreak);
            res.Max += res.Average;
            res.Min += res.Average;
            return res;
        }
    }
}
